import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)

/**
 * Write a description of class Ninja here.
 * 
 * @author (your name) 
 * @version (a version number or a date)
 */
public class Ninja extends Actor
{
    private boolean isKeyPressed;
    private boolean facingRight;
    private boolean isJumping;
    private boolean isLanceKnife;
    private boolean isDown;
    private boolean isAtack;
    private boolean isDead;
    
    private int iL = 0;
    private int TimeK = 0;
    protected int Salud;
    protected int Vidas;
    protected int Cuchillos;
    protected int Puntos;
    private int Speed;
    private int Scroll;
    private int Nivel;
    private int NivelAux;
    private int verticalSpeed = 0;
    private int acceleration = 1;
    private int animationCounter;
    private int animationDead;
    private int animationKnife;
    private int jumpDistance = 15;
    private int ninjaCentro;
    private int ninjaA;
    private Daga daga;
    private Onda onda;
    private final int NUM_IMAG = 4;
    
    private GreenfootSound golpeCerca;
    private GreenfootSound golpeadoCuervo;
    
    private final GreenfootImage muertoCerca = new GreenfootImage("ninjaMC.png");
    
    private final GreenfootImage AtackRight = new GreenfootImage("ninjaE.png");
    private final GreenfootImage AtackLeft = new GreenfootImage(AtackRight);
    
    private final GreenfootImage DuckingR = new GreenfootImage("ninjaA.png");
    private final GreenfootImage DuckingL = new GreenfootImage(DuckingR);
    
    private final GreenfootImage LanceKR = new GreenfootImage("ninjaLC.png");
    private final GreenfootImage LanceKL = new GreenfootImage(LanceKR);
    
    private final GreenfootImage ImagenNR = new GreenfootImage("ninja.PNG");
    private final GreenfootImage ImagenNL = new GreenfootImage(ImagenNR);
    
    private final GreenfootImage JumpRight = new GreenfootImage("ninjaB0.png");
    private final GreenfootImage JumpLeft = new GreenfootImage(JumpRight);
    private final GreenfootImage DownRight = new GreenfootImage("ninjaB1.png");
    private final GreenfootImage DownLeft = new GreenfootImage(DownRight);
    
    private final GreenfootImage[] ImagensWR = new GreenfootImage[NUM_IMAG];//Arreglo de la imagenes de caminar Derecha de el jugador
    private final GreenfootImage[] ImagensWL = new GreenfootImage[NUM_IMAG];//Arreglo para las imagenes de caminar Izquierda de el jugador
    
    public Ninja(){
         Salud = 100;
         Vidas = 3;
         Puntos = 0;
         Cuchillos = 5;
         Speed = 6;    
         Scroll = 1;
         Nivel = 1;
         NivelAux = 1;
         animationCounter = 0;
         animationDead = 0;
         animationKnife = 0;
         facingRight = true;
         isJumping = false;
         isLanceKnife = false;
         isAtack = false;
         isDown = false;
         isDead = false;
         
         ImagenNL.mirrorHorizontally();//voltea imagen para ir hacia la izquierda
         JumpLeft.mirrorHorizontally();//voltea imagen para brincar hacia la Izquierda
         DownLeft.mirrorHorizontally();//Volte la imagen caer hacia la Izquierda
         LanceKL.mirrorHorizontally();//Voltea imagen hacia la izquierda lanza cuchillo
         DuckingL.mirrorHorizontally();//Voltea la imagen agachado hacia la Izquierda 
         AtackLeft.mirrorHorizontally(); //voltea ninja cuando esta atacando hacia la Izquierda
         
         for(int i = 0; i<NUM_IMAG; i++)
          ImagensWR[i] = new GreenfootImage("ninjaC"+i+".png");
          
          for(int i = 0; i<NUM_IMAG; i++){
             ImagensWL[i] = new GreenfootImage(ImagensWR[i]);
             ImagensWL[i].mirrorHorizontally();
            }
        
         golpeCerca = new GreenfootSound("golpeCerca.wav");
         golpeadoCuervo = new GreenfootSound("puñetaso.wav");
         
         ninjaCentro = getImage().getHeight() /2; 
         ninjaA = DownRight.getHeight() / 2;  
       }
       
    /**
     * Act - do whatever the Ninja wants to do. This method is called whenever
     * the 'Act' or 'Run' button gets pressed in the environment.
     */
    public void act() 
    {
      if(!isDead){
         checaTeclas(); 
         checaColiciones();
         Limtes();
        
         if(!checaSuelo())
          fall();
          else  
           isJumping = false;
                    
        }else
         IsDead();
        
          }
    
    /**
     * Checa teclas y hace las acciones
     */
      public void checaTeclas()
      {
        
          isKeyPressed = false;
          isDown = false;
          
          if((Greenfoot.isKeyDown("right") || Greenfoot.isKeyDown("d")) && (Greenfoot.isKeyDown("left") || Greenfoot.isKeyDown("a")))
          {
           detenCaminado();   
          }
          else if(Greenfoot.isKeyDown("right") || Greenfoot.isKeyDown("d"))
          {
            animationCounter ++;
            walkHR();
            isKeyPressed = true;
            facingRight = true;
          }
          else if(Greenfoot.isKeyDown("left") || Greenfoot.isKeyDown("a")){
            animationCounter ++;
            walkHL();
            isKeyPressed = true;
            facingRight = false;
            }
            
          if((Greenfoot.isKeyDown("up") || Greenfoot.isKeyDown("w")) && isJumping == false)//Brincar
          {
            isKeyPressed = true;
            jump();
           }
           
          if((Greenfoot.isKeyDown("down") || Greenfoot.isKeyDown("s")) && isJumping == false)
            {
             isKeyPressed = true;
             isDown = true;
             down();
            }
          
          if(Greenfoot.isKeyDown("r") && TimeK > 20 ) //Lanzar cuchillo
          {
             isKeyPressed = true;
             isLanceKnife = true;
             lanceKnife();
             TimeK = 0;
           }
          
           if(Greenfoot.isKeyDown("e") && TimeK > 20 && !isJumping){// Atacar
            isKeyPressed = true;
            isAtack = true;
            TimeK = 0;
            }
                      
          if(isAtack && !isLanceKnife){
            atack();
            }else
           if(isLanceKnife){                              
              lancingKnife();
                }
           else if(!isKeyPressed)
            {
             detenCaminado(); 
            }
          
          if(TimeK <25)//Este if es para que la variable Time no tome valores muy altos
             TimeK ++;//Sirve para el retraso de el ataca y de el cuchillo
             
          
    }
     
    public void lancingKnife(){
              animationKnife ++;
              
              if(animationKnife > 10){
                 isLanceKnife = false;
                 animationKnife = 0;
                }
                
              if(facingRight)
                setImage(LanceKR);
                else
                setImage(LanceKL);
               
              }
              
    public void detenCaminado()
       { 
      if(facingRight)
        setImage(ImagenNR);
        else 
          setImage(ImagenNL);
       }
    
    /**
     * Mueve el ninja a la Izquierda y cambia la imagen
     */
       public void walkHL(){
             
          setLocation (this.getX() - Speed, this.getY());
        
          if(isTouching(Roca.class) && getY() > 250 ){  
               setLocation (this.getX() + Speed, this.getY());
              }
              
        if(animationCounter < 5)
            setImage(ImagensWL[0]);
        else if(animationCounter < 10)
            setImage(ImagensWL[1]);
        else if(animationCounter < 15)
            setImage(ImagensWL[2]);
        else if(animationCounter < 20)
            setImage(ImagensWL[3]);
        else if(animationCounter == 20 )
                animationCounter = 0;
        
        }
      
          /**
           * Mueve el ninja a la Derecha y cambia sus imagenes
         
           */    
    public void walkHR(){
                    
        setLocation (this.getX() + Speed, this.getY());
       
        if(isTouching(Roca.class) && getY() > 250 ){  
               setLocation (this.getX() - Speed, this.getY());
              }
          
        if(animationCounter < 5)
            setImage(ImagensWR[0]);
        else if(animationCounter < 10)
            setImage(ImagensWR[1]);
        else if(animationCounter < 15)
            setImage(ImagensWR[2]);
        else if(animationCounter < 20)
            setImage(ImagensWR[3]);
        else if(animationCounter == 20 )
                animationCounter = 0;
                
             } 
                        
    public void jump(){
        verticalSpeed = verticalSpeed - jumpDistance;
        fall();       
       }
       
    public void fall(){
     
        setLocation ( getX(), getY() + verticalSpeed);
        verticalSpeed = verticalSpeed + acceleration;
        isJumping = true;
        checaSuelo();
                
        if (facingRight){            
            if(verticalSpeed > 0)
               setImage(DownRight);
               else
             setImage(JumpRight);
            }                    
        else{
             if(verticalSpeed > 0)
               setImage(DownLeft);
               else
                 setImage(JumpLeft);
            }
    }
   
    private boolean checaSuelo()
    {
        World mundo = getWorld();
        
        if (getY() < mundo.getHeight()-40 && getOneObjectAtOffset (-17, ninjaCentro-5, Roca.class) == null
        && getOneObjectAtOffset (17, ninjaCentro-5, Roca.class) == null)
        {
            return false; // no esta tocando el suelo.
        }
         
         if ( getY() > mundo.getHeight() -40 /*|| getY() > 220 && getOneObjectAtOffset (-17, ninjaCentro-5, Roca.class) != null
        && getOneObjectAtOffset (17, ninjaCentro-5, Roca.class) != null*/)
        {
             setLocation( getX(), getY()-1); 
        }
        
        verticalSpeed = 0; 
          return true;
                 }
    
    public void atack(){
        animationCounter ++;
               
        if(animationCounter > 10){
           Greenfoot.playSound("Espada.wav");
            isAtack = false;
            animationCounter = 0;
              World world = this.getWorld();         
             onda = new Onda(facingRight);
            world.addObject(onda, this.getX(), this.getY()-5);        
                
        }
        
        if(facingRight)
                setImage(AtackRight);
                else
                setImage(AtackLeft);
                
       
          }
          
    public void down(){
                 
           if(facingRight)
               setImage(DuckingR);
               else
               setImage(DuckingL);
           
          if(!isTouching(Roca.class)){  
               setLocation(getX(),296);
              }
              else 
                     setLocation(getX(),245);
             } 
        
    public void lanceKnife(){
        if(Cuchillos > 0){
          World world = this.getWorld();
          Greenfoot.playSound("Cuchillo.wav");
          daga = new Daga(facingRight);
          world.addObject(daga, this.getX(), this.getY()-5);
          disminuyeCuchillos();
        }else
          Greenfoot.playSound("NoCuchillos.wav");
         }
         
    public void disminuyeVida(){
             Vidas--;
             isDead = true;
             CambiaLetros(2);
       }
    
    public void aumentaVida(){
       Greenfoot.playSound("vida.wav");
       Vidas ++;
       CambiaLetros(2);
      }   
       
    public void disminuyeSalud(int less){
         Salud -= less;
         if(Salud < 0)
           disminuyeVida();
           
      }
      
    public void disminuyeCuchillos(){
     Cuchillos --;
     CambiaLetros(3);
    }
    
    public void disminuyePuntos(int puntos){
       if(Puntos > 0 ){
        Puntos -= puntos;        
        CambiaLetros(1);  
    }
      
    }
       
   public  void aumentaPuntos(int puntos){
    Puntos += puntos; 
    CambiaLetros(1);
    }
    
   public void aumentaSalud(){
      if(Salud <= 100)
       Salud += 20;
    else 
       aumentaVida();       
    }
    
   public void aumentaCuchillos(int cuchillos){
    Cuchillos += cuchillos;
    CambiaLetros(3);
    } 
        
   public int rsalud(){
    return Salud;
    } 
    
   public void checaColiciones(){
     
      Actor cuervo = getOneIntersectingObject(Cuervo.class);
      Actor cerca =  getOneIntersectingObject(Cerca.class);
      Actor ninjaM =  getOneIntersectingObject(NinjaM.class);
      Actor sumo =  getOneIntersectingObject(Sumo.class);
      Actor agujero =  getOneIntersectingObject(Agujero.class);
      
       if(cuervo != null){
          golpeadoCuervo.play();
          disminuyeSalud(10);
          if(cuervo.getX() > this.getX())
            this.setLocation(getX()- 20,getY());
            else
            this.setLocation(getX() + 20,getY()); 
        }
        
       if(isTouching(Moneda.class) && iL > 10){
         Greenfoot.playSound("coin.wav");
         removeTouching(Moneda.class);
         aumentaPuntos(5);
         iL = 0;
        }
        
       if(isTouching(Cuchillo.class)){
         Greenfoot.playSound("bonus.wav");
         removeTouching(Cuchillo.class);
         aumentaCuchillos(5);         
        }
        
       if(isTouching(Elixir.class))
       {
        Greenfoot.playSound("bonus.wav");
        removeTouching(Elixir.class);
        aumentaSalud();       
        }
        
       if(isTouching(Ladron.class)&& iL > 40){ 
           disminuyePuntos(10);
           iL = 0;        
        }
        
       if(iL < 50)
          iL ++;
          
       if(ninjaM != null){
          
           Greenfoot.playSound("puñetasoM.wav");
           
            if(ninjaM.getX() > this.getX())
            this.setLocation(getX()- 100,getY());
            else
            this.setLocation(getX() + 100,getY());
            
            this.disminuyeSalud(20);
        } 
        
        
       if(sumo != null){
           
           Greenfoot.playSound("golpeSumo.wav");
           
            if(sumo.getX() > this.getX())
            this.setLocation(getX()- 100,getY());
            else
            this.setLocation(getX() + 100,getY());
            
            this.disminuyeSalud(30);
        } 
        
       if(agujero != null){           
           Greenfoot.playSound("caer.WAV");
            this.setLocation(getX() ,getY()+ 200);
            this.disminuyeVida();
        }  
        
       if(cerca != null){
          golpeCerca.play();
          this.setLocation(getX(),300);
          this.setImage(muertoCerca);
          disminuyeVida();
                  }
          
    } 
    
   public void Limtes(){
    Niveles mundo = (Niveles)this.getWorld();
    if(NivelAux == 1){
    
      if(this.getX()>mundo.getWidth()+20 && Scroll == 1){
        Scroll = 2;
        mundo.preparaNivel1(Scroll);
        }else if (this.getX()>mundo.getWidth()+20 && Scroll == 2){
                  Scroll = 1;
                  NivelAux = 2;
                }
      
        }else if (NivelAux == 2 ){
                    
                   if( Nivel == 1 ){
                       Nivel = 2;
                       mundo.iniciaNivel(Nivel);
                       Scroll = 2;  
                    }
                    
                   if (this.getX()>mundo.getWidth()+20 && Scroll == 2){{
                        mundo.preparaNivel2(Scroll);
                        Scroll = 1;
                      }
                    }else if(this.getX()>mundo.getWidth()+20 && Scroll == 1)
                           NivelAux =3;
                                                       
                 }else if(NivelAux == 3 ){
                    
                     if(Nivel == 2 ){
                         Nivel = 3;
                         mundo.iniciaNivel(Nivel);
                         Scroll = 2;  
                             }
                      
                      if (this.getX()>mundo.getWidth()+20 && Scroll == 2){{
                        mundo.preparaNivel3(Scroll);
                        Scroll = 1;
                      }
                    }else if(this.getX()>mundo.getWidth()+20 && Scroll == 1)
                           NivelAux =4;        
                                      
                    }else if(NivelAux == 4){                    
                    mundo.iniciaNivel(NivelAux);                  
                    }
                
    }
    
   public void IsDead(){   
        Niveles mundo = (Niveles)this.getWorld();       
       if(Vidas > 0){
           Salud = 0;
         if(animationDead > 30){
           this.setLocation(40,280);
           isDead = false;
           Salud = 100;
           animationDead = 0;
          }
          
          animationDead ++;
          }else if(Vidas <= 0)
               mundo.iniciaNivel(-1);
       
     } 
     
   public int ninjaX(){
    return getX();
     }  
     
   public int ninjaY(){
    return getY();
     }
     
   public void CambiaLetros(int jug){
            
        if(jug == 1 ){
           Letrero nuevo = new Letrero("Puntos =  " + Puntos, 1);
           getWorld().addObject(nuevo,400,20);
            }else if(jug == 2 ){
            Letrero nuevo = new Letrero(" =  " + Vidas, 2);
            getWorld().addObject(nuevo,500,20);            
            }else if(jug == 3){
            Letrero nuevo = new Letrero(" =  " + Cuchillos, 3);
            getWorld().addObject(nuevo,600,20);
            }    
         }
         
  
    public void guardaPuntos()
      {
                
        if (UserInfo.isStorageAvailable()) 
        {
            UserInfo myInfo = UserInfo.getMyInfo();
            if (Puntos > myInfo.getScore() || myInfo.getScore()==0) 
            {
                myInfo.setScore(Puntos);
                myInfo.store();  // write back to server
            }
        }
             
      }     
    } 

